{
  lib,
  fetchgit,
  formats,
}:
let
  inherit (lib)
    concatStrings
    listToAttrs
    makeOverridable
    mapAttrsToList
    nameValuePair
    ;
  json = formats.json { };
in
rec {

  # Derive a pin file from workspace state.
  mkPinFile =
    workspaceState:
    assert workspaceState.version >= 5 && workspaceState.version <= 6;
    json.generate "Package.resolved" {
      version = 1;
      object.pins = map (dep: {
        package = dep.packageRef.name;
        repositoryURL = dep.packageRef.location;
        state = dep.state.checkoutState;
      }) workspaceState.object.dependencies;
    };

  # Make packaging helpers from swiftpm2nix generated output.
  helpers =
    generated:
    let
      inherit (import generated) workspaceStateFile hashes;
      workspaceState = lib.importJSON workspaceStateFile;
      pinFile = mkPinFile workspaceState;
    in
    rec {

      # Create fetch expressions for dependencies.
      sources = listToAttrs (
        map (
          dep:
          nameValuePair dep.subpath (fetchgit {
            url = dep.packageRef.location;
            rev = dep.state.checkoutState.revision;
            sha256 = hashes.${dep.subpath};
            fetchSubmodules = true;
          })
        ) workspaceState.object.dependencies
      );

      # Configure phase snippet for use in packaging.
      configure = ''
        mkdir -p .build/checkouts
        ln -sf ${pinFile} ./Package.resolved
        install -m 0600 ${workspaceStateFile} ./.build/workspace-state.json
      ''
      + concatStrings (
        mapAttrsToList (name: src: ''
          ln -s '${src}' '.build/checkouts/${name}'
        '') sources
      )
      + ''
        # Helper that makes a swiftpm dependency mutable by copying the source.
        swiftpmMakeMutable() {
          local orig="$(readlink .build/checkouts/$1)"
          rm .build/checkouts/$1
          cp -r "$orig" .build/checkouts/$1
          chmod -R u+w .build/checkouts/$1
        }
      '';

    };

}
